Node 回调嵌套

一、Node 回调嵌套

需求:使用 异步 方法读取文件,按顺序分别读取文件 A、B、C,之后将 A 、B、C 的内容拼接起来输出。在不借助第三方变量的情况下。

1.1 原始嵌套

1
2
3
4
5
6
7
8
9
10
11
12
const fs = require('fs');
const path = require('path');
fs.readFile(path.join(__dirname, '../file/A.txt'), 'utf-8', (error, dataA) => {
if (error) throw error;
fs.readFile(path.join(__dirname, '../file/B.txt'), 'utf-8', (error, dataB) => {
if (error) throw error;
fs.readFile(path.join(__dirname, '../file/C.txt'), 'utf-8', (error, dataC) => {
if (error) throw error;
console.log(dataA + dataB + dataC);
})
})
})

代码的可阅读性极差,维护起来也是相当困难

1.2 使用 ES6 的 promise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const fs = require('fs');
const path = require('path');
new Promise((resolve) => {
fs.readFile(path.join(__dirname, '../file/A.txt'), 'utf-8', (error, dataA) => {
if (error) throw error;
resolve(dataA);
})
}).then((dataA) => {
return new Promise((resolve)=>{
fs.readFile(path.join(__dirname, '../file/B.txt'), 'utf-8', (error, dataB) => {
if (error) throw error;
resolve (dataA + dataB);
})
})
}).then((dataAB)=>{
fs.readFile(path.join(__dirname, '../file/C.txt'), 'utf-8', (error, dataC) => {
if (error) throw error;
console.log(dataAB + dataC);
})
})

1.3 用第三方模块 async

1
$ npm i async
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const fs = require('fs');
const path = require('path');
const async = require('async');

async.series([
(callback) => {
fs.readFile(path.join(__dirname, '../file/A.txt'), 'utf-8', (error, data) => {
if (error) throw error;
callback(null, data);
})
},
(callback) => {
fs.readFile(path.join(__dirname, '../file/B.txt'), 'utf-8', (error, data) => {
if (error) throw error;
callback(null, data);
})
},
(callback) => {
fs.readFile(path.join(__dirname, '../file/C.txt'), 'utf-8', (error, data) => {
if (error) throw error;
callback(null, data);
})
}
],
(err, results) => {
//results 为一个数组,里面包含了上面所有回调的 data
console.log(results.toString());
}
);

1.4 使用 js 的 async/await

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const fs = require('fs');
const path = require('path');

function readA() {
return new Promise((resolve) => {
fs.readFile(path.join(__dirname, '../file/A.txt'), 'utf-8', (error, dataA) => {
if (error) throw error;
resolve(dataA);
})
})
}

function readB() {
return new Promise((resolve) => {
fs.readFile(path.join(__dirname, '../file/B.txt'), 'utf-8', (error, dataB) => {
if (error) throw error;
resolve(dataB);
})
})
}

function readC() {
return new Promise((resolve) => {
fs.readFile(path.join(__dirname, '../file/C.txt'), 'utf-8', (error, dataC) => {
if (error) throw error;
resolve(dataC);
})
})
}

// 调用
async function readABC() {
const aTxt = await readA();
const bTxt = await readB();
const cTxt = await readC();
console.log(aTxt + bTxt + cTxt);
}
readABC();

未完待续

本文结束,感谢您的阅读